var mysql = require('njserver').mysql;
var dataMapper = require('../mapper/dataMapper');

//将62进制转成10进制
function to_62_to_10(str) {
    var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
        radix = chars.length,
        len = str.length,
        i = 0,
        origin_number = 0;
    while (i < len) {
        origin_number += Math.pow(radix, i++) * chars.indexOf(str.charAt(len - i) || 0);
    }
    return origin_number;
}

module.exports = {
    getData: function (param, callback) {
        this.tableIsExist(dataMapper.getData, param, callback);
    },

    updateData: function (param, callback) {
        this.tableIsExist(dataMapper.updateData, param, callback);
    },

    delData: function (param, callback) {
        this.tableIsExist(dataMapper.delData, param, callback);
    },

    insertData: function (param, callback) {
        this.tableIsExist(dataMapper.insertData, param, callback);
    },

    scriptData: function (param, callback) {
        mysql.execMapper(dataMapper.getScript, param, function (err, rows, fields) {
            if (err) {
                callback(err);
                return;
            }

            if (rows.length == 0) {
                callback({
                    msg: '查询不到记录'
                });
                return;
            }

            callback(err, rows, fields);
        });
    },

    sqlData: function (param, callback) {
        var that = this;
        mysql.execMapper(dataMapper.getSql, param, function (err, rows) {
            if (err) {
                callback(err);
                return;
            }

            if (rows.length == 0) {
                callback({
                    msg: '查询不到记录'
                });
                return;
            }

            that.fetchData(rows[0].description, param, callback);
        });
    },

    tableIsExist: function (sql, param, callback) {
        if (sysConfig.tableRoute && sysConfig.tableRoute[param.TableId]) {
            param.TableName = sysConfig.tableRoute[param.TableId];
            delete param.TableId;
            this.fetchData(sql(param), param, callback);
        } else {
            var that = this;
            param.TableId = to_62_to_10(param.TableId)
            mysql.execMapper(dataMapper.tableIsExist, param, function (err, rows) {
                if (err) {
                    callback(err);
                    return;
                }

                if (rows.length == 0) {
                    callback({
                        msg: '查询不到记录'
                    });
                    return;
                }

                delete param.TableId;
                param.TableName = rows[0].tableName;
                that.fetchData(sql(param), param, callback);
            });
        }
    },

    fetchData: function (sql, param, callback) {
        if (param.takeNum && param.takeNum > 0 && param.pageIndex && param.pageIndex > 0) {
            var countSql = this.getCountSql(sql);
            sql += ' limit ' + (param.pageIndex - 1) * param.takeNum + ',' + param.takeNum;
            mysql.exec(countSql, param, function (err, rows, fields) {
                if (err) {
                    callback(err);
                    return;
                }

                var count = parseInt(rows[0].total);
                var pageCount = Math.floor(count / param.takeNum);
                if (count % param.takeNum != 0)
                    pageCount++;
                if (pageCount == 0)
                    pageCount = 1;

                mysql.exec(sql, param, function (err, rows, fields) {
                    if (err) {
                        callback(err);
                    } else {
                        callback(err, {
                            result: 'ok',
                            data: rows,
                            count: count,
                            pageCount: pageCount,
                            pageIndex: parseInt(param.pageIndex),
                            takeNum: parseInt(param.takeNum)
                        }, fields);
                    }
                });
            });
        } else {
            mysql.exec(sql, param, function (err, rows, fields) {
                if (err) {
                    callback(err);
                } else {
                    callback(err, {
                        result: 'ok',
                        data: rows,
                        count: rows.length,
                        pageCount: -1,
                        pageIndex: -1,
                        takeNum: rows.length
                    }, fields);
                }
            });
        }
    },

    getCountSql: function (sql) {
        var originSql = sql;
        var cols = {};
        var reg = /\([^\(\)]+?\)/;
        var ms = null;
        var i = 0;
        while ((ms = reg.exec(sql))) {
            var str = 'flynn_sql_index_' + i;
            cols[str] = ms;
            sql = sql.replace(ms, str);
            i++;
        }
        sql = sql.replace(/select([\s\S]+?)from/i, 'select count(0) total from');

        var group = false;
        reg = /group([\s]+)by/ig;
        if (reg.test(sql))
            group = true;

        reg = /flynn_sql_index_[0-9]+/;
        ms = null;
        while ((ms = reg.exec(sql))) {
            sql = sql.replace(ms, cols[ms]);
        }

        if (group)
            return `select count(0) total from(${originSql})a`;
        else
            return sql;
    }
};